from django import forms
from .bootstrap import BootstrapForm
from web import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django.conf import settings
from utils.tencent.sms import send_sms_single
from django_redis import get_redis_connection
from utils import encrypt
import random

class RegisterModelForm(BootstrapForm, forms.ModelForm):
    '''
    注册页面显示的form的验证
    '''
    password = forms.CharField(
            label='密码',
            min_length=8,
            max_length=64,
            error_messages={
                'min_length': "密码长度不能小于8个字符",
                'max_length': "密码长度不能大于64个字符"
            },
            widget=forms.PasswordInput()
        )

    confirm_password = forms.CharField(
        label='重复密码',
        min_length=8,
        max_length=64,
        error_messages={
            'min_length': "重复密码长度不能小于8个字符",
            'max_length': "重复密码长度不能大于64个字符"
        },
        widget=forms.PasswordInput())
    mobile_phone = forms.CharField(label='手机号', validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ])

    code = forms.CharField(
            label='验证码',
            widget=forms.TextInput())

    class Meta:
        model = models.UserInfo
        fields = ['username', 'email', 'password', 'confirm_password', 'mobile_phone', 'code']

    def clean_username(self):
        '''
        验证用户名
        :return:
        '''
        #获取用户名
        username=self.cleaned_data.get('username')
        exist=models.UserInfo.objects.filter(username=username).exists()
        if exist:
            # raise ValidationError('用户名已存在')
            self.add_error('username','用户名已存在')
        return username

    def clean_email(self):
        '''
        验证邮箱
        :return:
        '''
        email=self.cleaned_data.get('email')
        exist=models.UserInfo.objects.filter(email=email).exists()
        if exist:
            raise ValidationError('邮箱已存在')
        else:
            return email

    def clean_password(self):
        '''
        验证密码
        :return:
        '''
        password=self.cleaned_data.get('password')
        return encrypt.md5(password)

    def clean_confirm_password(self):
        '''
        验证第二次输入的密码
        :return:
        '''
        password=self.cleaned_data.get('password')
        confirm_password=encrypt.md5(self.cleaned_data.get('confirm_password'))
        if password !=confirm_password:
            raise ValidationError('两次密码不一致')
        else:
            return confirm_password

    def clean_mobile_phone(self):
        '''
        验证手机号
        :return:
        '''
        mobile_phone=self.cleaned_data.get('mobile_phone')
        exist=models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exist:
            raise ValidationError('手机号已经存在')
        return mobile_phone

    def clean_code(self):
        '''
        验证短信
        :return:
        '''
        #######把短信接口配置好后 ↓ 删除#########
        return self.cleaned_data.get('code')
        #######把短信接口配置好后 ↑ 删除#########


        code=self.cleaned_data.get('code')
        conn=get_redis_connection()
        mobile_phone = self.cleaned_data.get('mobile_phone')
        if not mobile_phone:
            return code
        conn.get(mobile_phone)
        redis_code=conn.get(mobile_phone)
        if not redis_code:
            raise ValidationError('验证码失效或者没有发送 ，请重试')
        redis_code_str=str(redis_code,encoding='utf8')
        if code.strip()!=redis_code_str:
            raise ValidationError('验证码错误，请重新输入')
        return code
    # def clean(self):
    #     if self.cleaned_data.get('confirm_password'):
    #         self.cleaned_data.pop('confirm_password')
    #     if self.cleaned_data.get('code'):
    #         self.cleaned_data.pop('code')
    #     return self.cleaned_data

class SmsSendModelForm(forms.Form):

    '''
    手机号码验证 并且发送短信 存储短信到redis
    '''
    mobile_phone=forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ])

    #验证手机号码时候把request对象传送过来
    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request=request

    def clean_mobile_phone(self):
        '''
        手机号验证的钩子函数
        :return:
        '''
        #获取手机号
        mobile_phone=self.cleaned_data.get('mobile_phone')

        #获取需要的短信模板
        tpl=self.request.GET.get('tpl')
        template_id=settings.TENCENT_SMS_TEMPLATE.get(tpl)
        #获取随机的验证码
        code=random.randrange(1000,9999)
        #如果模板不存在  raise 错误
        if not template_id:
            # self.add_error('mobile_phone','短信末班错误')
            raise ValidationError('短信模板错误')
        #判断手机号是否在数据中存在
        exist=models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        #登录时候  如果手机号不存在 报错
        if tpl=='login':
            if not exist:
                raise ValidationError('手机号不存在')
        #注册的时候  如果手机号存在 报错
        else:
            if exist:
                raise ValidationError('手机号已经存在')
        #发送短信
        sms=send_sms_single(mobile_phone,template_id,[code,])
        if sms['result']!=0:
            raise ValidationError('短信发送失败,{}'.format(sms['errmsg']))
        #短信发送成功  把验证码存入redis中
        conn=get_redis_connection()
        conn.set(mobile_phone,code,ex=60)
        return mobile_phone

class LoignUserPwdModelForm(BootstrapForm,forms.ModelForm):
    '''
    用户名密码登录 显示和验证的form
    '''
    username=forms.CharField(label='用户名或邮箱')
    password=forms.CharField(label='密码',widget=forms.PasswordInput())
    code=forms.CharField(label='图片验证码',)
    class Meta:
        model=models.UserInfo
        fields=['username','password','code']

    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request=request

    def clean_password(self):
        password=self.cleaned_data.get('password')
        return encrypt.md5(password)

    def clean_code(self):
        code=self.cleaned_data.get('code')
        code_session=self.request.session.get('image_code')
        if not code_session:
            raise ValidationError('验证码过期，请重新输入')
        if code.strip().upper()==code_session.strip().upper():
            return code
        else:
            raise ValidationError('验证码错误')


class LoginSmsModelForm(forms.Form):
    '''
    用户短信登录 验证和显示的form
    '''
    mobile_phone=forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$','手机号格式错误'),],widget=forms.TextInput(attrs={'class':'form-control','placeholder':'请输入手机号'}))
    code=forms.CharField(label='短信',widget=forms.TextInput(attrs={'class':'form-control','placeholder':'请输入手机号'}))

    def clean_mobile_phone(self):
        '''
        检验手机号码
        :return:
        '''
        mobile_phone=self.cleaned_data.get('mobile_phone')
        exist=models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if not exist:
            raise ValidationError('手机号不存在')
        return mobile_phone

    def clean_code(self):

        #######把短信接口配置好后 ↓ 删除#########
        return self.cleaned_data.get('code')
        #######把短信接口配置好后 ↑ 删除#########


        code=self.cleaned_data.get('code')
        mobile_phone=self.cleaned_data.get('mobile_phone')
        if not mobile_phone:
            return code
        try:
            conn=get_redis_connection()
            code_redis=conn.get(mobile_phone)
        except ConnectionError:
            raise ValidationError('获取验证码失败')
        if not code_redis:
            raise ValidationError('验证码已过期或未发送，请重新发送')
        if code.strip()!=str(code_redis,encoding='uft8'):
            raise ValidationError('验证码错误')
        return code


